﻿
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Object = UnityEngine.Object;

namespace HHHFramework
{
    public struct PoolManagerKeys
    {
        public string assetName;
        public string assetBundleName;
        public Type assetType;

        public bool Equals(Type assetType, string assetName, string assetBundleName = null)
        {
            if (this.assetName == assetName && this.assetBundleName == assetBundleName && this.assetType == assetType)
            {
                return true;
            }
            return false;
        }

    }
    public class PoolManager : MonoSingleton<PoolManager>
    {

        public void Ini()
        {
            Debug.Log("PoolManager Ini");
        }

        private Dictionary<PoolManagerKeys, SpawnPool> spawnPoolDic = new Dictionary<PoolManagerKeys, SpawnPool>();

        /// <summary>
        /// 分配一个资源 如果该资源没有在对象池中则从资源中加载   UIPrefabs = PoolManager.Instance.GetResOrCreatPrefab<GameObject>(SpawnPoolType.UI, "resources://" + uiPath);
        /// </summary>
        /// <typeparam name="T">资源类型</typeparam>
        /// <param name="spawnPoolType">资源产生器类型</param>
        /// <param name="assetName">资源名称</param>
        /// <param name="assetBundleName">资源Assetbundle名称</param>
        /// <param name="count">资源的最大数值</param>
        /// <returns></returns>
        public T AllocatePrefab<T>(string assetName, string assetBundleName = null, int count = 1) where T : Object
        {
            PoolManagerKeys poolManagerKeys = new PoolManagerKeys() {
                assetName = assetName,
                assetBundleName = assetBundleName,
                assetType = typeof(T)
            };
            if (!spawnPoolDic.ContainsKey(poolManagerKeys))
            {
                CreateSpawnPool<T>(assetName, assetBundleName, count);
            }
            return spawnPoolDic[poolManagerKeys].Allocate<T>(assetName, assetBundleName);
        }
        public void AsyncAllocatePrefab<T>(string assetName, string assetBundleName = null, int count = 1, Action<T> allocated = null) where T : Object
        {
            PoolManagerKeys poolManagerKeys = new PoolManagerKeys()
            {
                assetName = assetName,
                assetBundleName = assetBundleName,
                assetType = typeof(T)
            };
            if (!spawnPoolDic.ContainsKey(poolManagerKeys))
            {
                CreateSpawnPool<T>(assetName, assetBundleName,count);
            }
            spawnPoolDic[poolManagerKeys].AsyncAllocate<T>(assetName, assetBundleName, allocated);
        }
        private void CreateSpawnPool<T>(string assetName, string assetBundleName, int count) where T : Object
        {
            var spawnPool = new SpawnPool();
            spawnPool.SpawnPoolCreate<T>(assetName, assetBundleName, count);
            PoolManagerKeys poolManagerKeys = new PoolManagerKeys()
            {
                assetName = assetName,
                assetBundleName = assetBundleName,
                assetType = typeof(T)
            };
            spawnPoolDic.Add(poolManagerKeys, spawnPool);

        }

        /// <summary>
        /// 收回数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="res"></param>
        public void Retrieve<T>(T gameObject,string assetName, string assetBundleName = null) where T : Object
        {
            PoolManagerKeys poolManagerKeys = new PoolManagerKeys()
            {
                assetName = assetName,
                assetBundleName = assetBundleName,
                assetType = typeof(T)
            };
            if (spawnPoolDic.ContainsKey(poolManagerKeys))
            {
                spawnPoolDic[poolManagerKeys].Push<T>(gameObject);
            }
        }
        public void ReleaseSpawnPool<T>(string assetName, string assetBundleName = null)
        {
            PoolManagerKeys poolManagerKeys = new PoolManagerKeys()
            {
                assetName = assetName,
                assetBundleName = assetBundleName,
                assetType = typeof(T)
            };
            spawnPoolDic[poolManagerKeys].ReleaseSpawnPool();
            spawnPoolDic.Remove(poolManagerKeys);
        }





    }

}
